package cn.itcast.nems.studentrecord.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Assert;
import cn.itcast.ic.common.bean.Page;
import cn.itcast.ic.common.exception.v2.BizExceptionProducer;
import cn.itcast.ic.msplatform.api.model.Dictionary;
import cn.itcast.nems.approval.bpm.eventstrategy.BpmEventStrategy;
import cn.itcast.nems.approval.dao.entity.ApprovalConfig;
import cn.itcast.nems.approval.dao.entity.ApprovalForm;
import cn.itcast.nems.approval.enumeration.ApprovalErrorBodyEnum;
import cn.itcast.nems.approval.service.ApprovalConfigService;
import cn.itcast.nems.approval.service.ApprovalFormFlowService;
import cn.itcast.nems.approval.service.ApprovalFormService;
import cn.itcast.nems.base.api.ClazzApi;
import cn.itcast.nems.base.dto.ClazzDTO;
import cn.itcast.nems.base.dto.DictionaryDTO;
import cn.itcast.nems.base.service.DictionaryService;
import cn.itcast.nems.common.PageQueryModel;
import cn.itcast.nems.common.account.AccountHolder;
import cn.itcast.nems.common.enumeration.BizNumberTypeEnum;
import cn.itcast.nems.common.enumeration.NemsErrorBodyEnum;
import cn.itcast.nems.common.service.BizNumberService;
import cn.itcast.nems.employee.service.EmployeeService;
import cn.itcast.nems.journal.enumeration.JournalStateEnum;
import cn.itcast.nems.journal.util.JournalUtil;
import cn.itcast.nems.manager.activity.BpmWorkflowManager;
import cn.itcast.nems.manager.util.CustomBeanUtil;
import cn.itcast.nems.oldems.dto.oldapi.EmsApiResult;
import cn.itcast.nems.oldems.service.sync.OldEmsSyncService;
import cn.itcast.nems.studentrecord.constant.ReferenceTypeEnum;
import cn.itcast.nems.studentrecord.dao.condition.ApprovalType;
import cn.itcast.nems.studentrecord.dao.condition.ReceivableAdjustmentState;
import cn.itcast.nems.studentrecord.dao.dataobject.ReceivableAdjustmentDO;
import cn.itcast.nems.studentrecord.dao.entity.ReceivableAdjustment;
import cn.itcast.nems.studentrecord.dao.entity.StudentRecord;
import cn.itcast.nems.studentrecord.dao.mapper.ReceivableAdjustmentMapper;
import cn.itcast.nems.studentrecord.dto.ReceivableAdjustmentDTO;
import cn.itcast.nems.studentrecord.dto.ReceivableAdjustmentQueryDTO;
import cn.itcast.nems.studentrecord.dto.StudentRecordDTO;
import cn.itcast.nems.studentrecord.dto.studentrecord.StudentRecordReceivableCreateDTO;
import cn.itcast.nems.studentrecord.enumeration.StudentRecordErrorBodyEnum;
import cn.itcast.nems.studentrecord.service.ReceivableAdjustmentService;
import cn.itcast.nems.studentrecord.service.studentrecord.StudentRecordReceivableService;
import cn.itcast.nems.studentrecord.service.studentrecord.StudentRecordService;
import cn.itcast.nems.studentrecord.util.BusinessApprovalFlowServiceUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 调价单业务逻辑实现类
 *
 * @author ChangLu.Gao
 * @version v1.0
 * @program nems-server
 * @description
 * @date 2023/11/21 18:36
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class ReceivableAdjustmentServiceImpl extends ServiceImpl<ReceivableAdjustmentMapper, ReceivableAdjustment>
        implements ReceivableAdjustmentService, BpmEventStrategy {

    private final BpmWorkflowManager bpmWorkflowManager;

    private final StudentRecordService studentRecordService;

    private final ApprovalFormService approvalFormService;

    private final BizNumberService bizNumberService;

    private final ApprovalFormFlowService approvalFormFlowService;

    private final ApprovalConfigService approvalConfigService;

    private final EmployeeService employeeService;

    private final StudentRecordReceivableService studentRecordReceivableService;

    private final DictionaryService dictionaryService;

    private final ClazzApi clazzApi;

    private final OldEmsSyncService oldEmsSyncService;

    private final static String REASON_CODE = "NEMS_AJUSTMENT_REASON";

    public final static String BUSINESS_LINE_CODE = "DUAN_XUN";
    public final static String BUSINESS_LINE_NAME = "短训";


    @Override
    public String getStrategyName() {
        return ApprovalFormService.JournalType.RECEIVABLE_ADJUSTMENT.name();
    }

    @Override
    public Page<ReceivableAdjustmentDTO> pageList(PageQueryModel<ReceivableAdjustmentQueryDTO> queryModel) {
        com.baomidou.mybatisplus.extension.plugins.pagination.Page<ReceivableAdjustmentDO> page = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>();
        page.setCurrent(queryModel.getPageNumber());
        page.setSize(queryModel.getPageSize());
        ReceivableAdjustmentDO condition = CustomBeanUtil.copyProperties(queryModel.getCondition(), new ReceivableAdjustmentDO());
        String rangeType = condition.getRangeType();
        if (ApprovalType.ALL.name().equals(rangeType)) {
            if (!AccountHolder.hasEmployeeGroups()) {
                return Page.of(queryModel.getPageNumber(), queryModel.getPageSize(), 0, null);
            }
            condition.setEmployeeGroups(AccountHolder.getEmployeeGroups());
        }
        this.explicitApprovalRange(condition, queryModel.getCondition());
        JournalUtil.invokeByApprovalType(this.getJournalIdFormIds(), condition, ApprovalFormService.JournalType.RECEIVABLE_ADJUSTMENT.name(),
                ApprovalType.valueOf(queryModel.getCondition().getRangeType()));

        IPage<ReceivableAdjustmentDO> pageData = super.getBaseMapper().findPageList(page, condition);
        if (null == pageData || CollectionUtil.isEmpty(pageData.getRecords())) {
            return Page.of(queryModel.getPageNumber(), queryModel.getPageSize(), 0, null);
        }
        return Page.of(queryModel.getPageNumber(),
                queryModel.getPageSize(),
                (int) pageData.getTotal(),
                pageData.getRecords().stream().map(o -> BusinessApprovalFlowServiceUtil.convert(o, condition, allDictionary())).toList()
        );
    }

    private List<String> getJournalIdFormIds() {
        ApprovalConfig config = approvalConfigService.getByJournalCode(ApprovalFormService.JournalType.RECEIVABLE_ADJUSTMENT.name());
        Assert.notNull(config, BizExceptionProducer.produce(ApprovalErrorBodyEnum.MUST_CONFIG_APPROVAL_CONFIG, ApprovalFormService.JournalType.RECEIVABLE_ADJUSTMENT.getCnName()));
        return bpmWorkflowManager.findWaitApproval(config.getBpmProcessKey(), AccountHolder.getRequiredAccount());
    }

    private Map<String, String> allDictionary() {
        DictionaryDTO dto = new DictionaryDTO();
        dto.setParentCode(REASON_CODE);
        List<Dictionary> list = dictionaryService.list(dto);
        Assert.notEmpty(list, BizExceptionProducer.produce(NemsErrorBodyEnum.DATA_EXIST, REASON_CODE));
        Map<String, String> dictionaryMap = list.stream().collect(Collectors.toMap(Dictionary::getCode, Dictionary::getName, (oldValue, newValue) -> newValue));
        log.info("【调价单】字典列表：{}", JSON.toJSONString(dictionaryMap, SerializerFeature.DisableCircularReferenceDetect));
        return dictionaryMap;
    }

    /**
     * 明确审批范围
     *
     * @param condition 查询条件
     * @author 高昌露
     * @since 2023/11/22 15:11
     */
    private void explicitApprovalRange(@NonNull ReceivableAdjustmentDO adjustmentDO, @NonNull ReceivableAdjustmentQueryDTO condition) {
        if (null != condition.getId()) {
            adjustmentDO.setIds(List.of(condition.getId()));
        }
        if (null != condition.getStudentNo()) {
            List<StudentRecordDTO> studentRecordDTOList = studentRecordService.queryByStudentNo(condition.getStudentNo());
            if (CollectionUtil.isNotEmpty(studentRecordDTOList)) {
                adjustmentDO.setStudentRecordIds(studentRecordDTOList.stream().map(StudentRecordDTO::getId).toList());
            }
        }
        if (condition.getMinAmount() != null) {
            adjustmentDO.setMinAmount(condition.getMinAmount().multiply(new BigDecimal(100)).intValue());
        }
        if (condition.getMaxAmount() != null) {
            adjustmentDO.setMaxAmount(condition.getMaxAmount().multiply(new BigDecimal(100)).intValue());
        }
    }

    /**
     * 获取待当前登录人审批的凭单ID
     *
     * @return java.util.List<java.lang.String>
     * @author 高昌露
     * @since 2023/11/29 15:12
     */
    private List<String> getWaitApprovalJournalIds() {
        ApprovalConfig config = approvalConfigService.getByJournalCode(ApprovalFormService.JournalType.RECEIVABLE_ADJUSTMENT.name());
        Assert.notNull(config, BizExceptionProducer.produce(NemsErrorBodyEnum.DATA_EXIST, "调价凭单流程配置信息在"));
        List<String> waitApprovalFormIds = bpmWorkflowManager.findWaitApproval(config.getBpmProcessKey(), AccountHolder.getRequiredAccountInfo().getEmail());
        if (CollectionUtil.isEmpty(waitApprovalFormIds)) {
            return new ArrayList<>();
        }
        var approvalFormList = this.approvalFormService.listByIds(waitApprovalFormIds);
        return new ArrayList<>(approvalFormList.stream().map(ApprovalForm::getJournalId).toList());
    }

    @Override
    public ReceivableAdjustmentDTO queryById(@NonNull String id) {
        var record = super.getBaseMapper().selectById(id);
        Assert.notNull(record, BizExceptionProducer.produce(NemsErrorBodyEnum.DATA_EXIST, "调价凭单在"));
        var approvalFormList = this.approvalFormService.getActiveByJournalId(ApprovalFormService.JournalType.RECEIVABLE_ADJUSTMENT, record.getId(), null);
        StudentRecordDTO studentRecordDTO = this.studentRecordService.queryById(record.getStudentRecordId());
        var employee = employeeService.findOneByEmail(record.getCreatedBy());
        var result = BusinessApprovalFlowServiceUtil.convert(studentRecordDTO, record, employee);
        if (CollectionUtil.isNotEmpty(approvalFormList)) {
            result.setFormId(approvalFormList.get(0).getId());
        }
        // TODO 区分ApprovalType，待我审批、已办事项不限制数据权限
//        Assert.isFalse(!AccountHolder.hasEmployeeGroups(result.getClazzCampusId(), result.getClazzSubjectId()), BizExceptionProducer.unauthorized("暂无权限"));
        // 验证字段 code , 来自字典服务
        String reasonDescription = dictionaryService.getNameByParentCode(REASON_CODE, result.getReason());
        Assert.notEmpty(reasonDescription, BizExceptionProducer.produce(NemsErrorBodyEnum.DICTIONARY_EXIST, result.getReason()));
        result.setReasonDescription(reasonDescription);
        result.setNeedApproval(this.getWaitApprovalJournalIds().contains(id));
        result.setBusinessLineCode(BUSINESS_LINE_CODE);
        result.setBusinessLineName(BUSINESS_LINE_NAME);
        return result;
    }

    @Override
    public ReceivableAdjustmentDTO queryByStudentRecord(@NonNull String studentRecordId) {
        StudentRecordDTO studentRecordDTO = this.studentRecordService.queryById(studentRecordId);
        return BusinessApprovalFlowServiceUtil.convert(studentRecordDTO, null, null);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String saveOrEdit(@NonNull ReceivableAdjustmentDTO reqParam) {
        ReceivableAdjustment record;
        if (StringUtils.isNotBlank(reqParam.getId())) {
            record = super.getBaseMapper().selectById(reqParam.getId());
            Assert.isTrue(ReceivableAdjustmentState.canEdit(record.getState()), BizExceptionProducer.produce(StudentRecordErrorBodyEnum.APPROVE_CAN_NOT_EDIT, "凭单当前状态不可编辑"));
        } else {
            record = new ReceivableAdjustment();
        }
        ReceivableAdjustmentDTO dto = this.queryByStudentRecord(reqParam.getStudentRecordId());
        BeanUtils.copyProperties(dto, record, "id");
        // 维护校区、学科信息
        this.invokeClazzInfo(record);
        record.setSpecialFlag(reqParam.getSpecialFlag());
        record.setRemark(reqParam.getRemark());
        // 验证字段 code , 来自字典服务
        String reasonDescription = dictionaryService.getNameByParentCode("NEMS_AJUSTMENT_REASON", reqParam.getReason());
        Assert.notEmpty(reasonDescription, BizExceptionProducer.produce(NemsErrorBodyEnum.DICTIONARY_EXIST, reqParam.getReason()));
        record.setReason(reqParam.getReason());
        record.setOriginalAmount(dto.getOriginalAmount().multiply(BusinessApprovalFlowServiceUtil.DENOMINATOR).intValue());
        record.setAmount(reqParam.getAmount().multiply(BusinessApprovalFlowServiceUtil.DENOMINATOR).intValue());
        record.setCanAdjustmentAmount(dto.getCanAdjustmentAmount().multiply(BusinessApprovalFlowServiceUtil.DENOMINATOR).intValue());
        record.setTargetAmount((dto.getOriginalAmount().add(reqParam.getAmount())).multiply(BusinessApprovalFlowServiceUtil.DENOMINATOR).intValue());
        record.setState(ReceivableAdjustmentState.DRAFT);
        if (StringUtils.isBlank(record.getId())) {
            record.setId(bizNumberService.next(BizNumberTypeEnum.RECEIVABLE_ADJUSTMENT));
            super.baseMapper.insert(record);
        } else {
            super.baseMapper.updateById(record);
        }
        return record.getId();
    }

    private void invokeClazzInfo(ReceivableAdjustment receivableAdjustment) {
        StudentRecord studentRecord = studentRecordService.getById(receivableAdjustment.getStudentRecordId());
        Assert.notNull(studentRecord, BizExceptionProducer.produce(NemsErrorBodyEnum.DATA_EXIST, "学籍ID：" + receivableAdjustment.getStudentRecordId()));
        ClazzDTO clazzDTO = clazzApi.queryByClassId(studentRecord.getClazzId());
        log.info("【调价单】查询班级详情 班级ID：{} , 详情：{}", studentRecord.getClazzId(), JSON.toJSONString(clazzDTO));
        Assert.notNull(clazzDTO, BizExceptionProducer.produce(NemsErrorBodyEnum.DATA_EXIST, "班级ID：" + studentRecord.getClazzId()));
        receivableAdjustment.setClazzCampusId(clazzDTO.getSchoolId());
        receivableAdjustment.setClazzCampusName(clazzDTO.getSchoolName());
        receivableAdjustment.setClazzSubjectId(clazzDTO.getSubjectId());
        receivableAdjustment.setClazzSubjectName(clazzDTO.getSubjectName());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(@NonNull String id) {
        ReceivableAdjustment record = super.getBaseMapper().selectById(id);
        Assert.isTrue(ReceivableAdjustmentState.canEdit(record.getState()), BizExceptionProducer.produce(StudentRecordErrorBodyEnum.APPROVE_CAN_NOT_EDIT, "凭单当前状态不可删除"));
        super.baseMapper.deleteById(id);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String commitToBPM(ReceivableAdjustmentDTO dto) {
//        this.oldEmsSyncService.checkAndGetOldEmsSJcId(dto.getStudentRecordId());
        String id = this.saveOrEdit(dto);
        this.studentRecordService.locks(Set.of(dto.getStudentRecordId()), ReferenceTypeEnum.ADJUSTMENT, id);
        ReceivableAdjustment record = super.getBaseMapper().selectById(id);
        Assert.isTrue(ReceivableAdjustmentState.canEdit(record.getState()), BizExceptionProducer.produce(StudentRecordErrorBodyEnum.BAD_REQUEST, "凭单当前状态不可提交"));
        ApprovalConfig config = approvalConfigService.getByJournalCode(ApprovalFormService.JournalType.RECEIVABLE_ADJUSTMENT.name());
        Assert.notNull(config, BizExceptionProducer.produce(NemsErrorBodyEnum.DATA_EXIST, "调价凭单流程配置信息在"));
        record.setState(ReceivableAdjustmentState.PENDING);
        super.getBaseMapper().updateById(record);
        String formId = this.approvalFormService.start(ApprovalFormService.JournalType.RECEIVABLE_ADJUSTMENT, id, this.getVariables(dto), config.getBpmProcessKey());
        log.info("[调价单]员工({})提交了调价单({})-关联审批单({})", AccountHolder.getRequiredAccountInfo().getName(), id, formId);
        return id;
    }

    /**
     * <p>
     * 获取重读凭单工作流参数<br>
     * process_key: process_82092143ef8b4053bb4451909b9bdb3b<br>
     * 参数变量：<br>
     * 1、是否特殊审批 special_approval （"true"， "false"）<br>
     * 2、调价金额是否超过两千 is_amount_excessed_2000 （"true"， "false"）
     * </p>
     *
     * @param dto 提交工作流的请求参数
     * @author zhouwei
     * @since 2023/12/8 1:33 PM
     **/
    public HashMap<String, Object> getVariables(ReceivableAdjustmentDTO dto) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("special_approval", Objects.isNull(dto.getSpecialFlag()) || !dto.getSpecialFlag() ? "false" : "true");
        map.put("is_amount_excessed_2000", dto.getAmount().abs().compareTo(BigDecimal.valueOf(2000)) >= 0 ? "true" : "false");
        log.info("【调价单凭单-获取工作流参数】参数：{}", JSON.toJSONString(map));
        return map;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void inform(String formID, String targetAssignee) {
        approvalFormFlowService.inform(formID, targetAssignee);
        log.info("[调价单{}]触发了收到知会", formID);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Runnable finish(String formID) {
        var approvalForm = this.approvalFormService.getById(formID);
        Assert.notNull(approvalForm, BizExceptionProducer.produce(NemsErrorBodyEnum.DATA_EXIST, "审批单不存在"));
        var record = super.getBaseMapper().selectById(approvalForm.getJournalId());
        Assert.notNull(record, BizExceptionProducer.produce(NemsErrorBodyEnum.DATA_EXIST, "调价单不存在"));
        if (ReceivableAdjustmentState.FINISHED.equals(record.getState())) {
            return null;
        }
        record.setState(ReceivableAdjustmentState.FINISHED);
        super.baseMapper.updateById(record);
        this.studentRecordService.updateAdjustmentAmount(record.getStudentRecordId(), record.getAmount());
        this.studentRecordReceivableService.addStudentRecordReceivable(
                new StudentRecordReceivableCreateDTO(
                        record.getStudentRecordId(),
                        ReferenceTypeEnum.ADJUSTMENT,
                        record.getId(),
                        record.getId(),
                        record.getAmount(),
                        LocalDate.now()
                )
        );
        this.approvalFormService.finish(formID);
        this.studentRecordService.unlocks(Set.of(record.getStudentRecordId()), ReferenceTypeEnum.ADJUSTMENT, approvalForm.getJournalId());
        EmsApiResult syncResult = this.oldEmsSyncService.adjustPrice(record.getStudentRecordId(), record.getAmount(), record.getCreatedBy());
        Assert.isTrue(syncResult.isSuccess(),
                BizExceptionProducer.produce(StudentRecordErrorBodyEnum.BAD_REQUEST,
                        "调价功能同步老EMS失败, 表单ID:" + formID + ", 学籍ID: " + record.getStudentRecordId()
                )
        );
        log.info("[调价单{}]审批完成,流程结束", formID);
        return null;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void approve(String formID, ApprovalFormService.ApproveResult result, String comment, final String form, Integer applyType) {
        var approvalForm = this.approvalFormService.getById(formID);
        Assert.notNull(approvalForm, BizExceptionProducer.produce(NemsErrorBodyEnum.DATA_EXIST, "审批单不存在"));
        var record = super.getBaseMapper().selectById(approvalForm.getJournalId());
        Assert.notNull(record, BizExceptionProducer.produce(NemsErrorBodyEnum.DATA_EXIST, "调价单不存在"));
        Assert.isTrue(ReceivableAdjustmentState.canApprove(record.getState()),
                BizExceptionProducer.produce(StudentRecordErrorBodyEnum.WORKFLOW_NO_PENDING_APPROVING)
        );
//        if (ApprovalFormService.ApproveResult.REJECT.equals(result)) {
//            record.setState(ReceivableAdjustmentState.REJECTED);
//        } else {
//            record.setState(ReceivableAdjustmentState.APPROVING);
//        }
//        super.baseMapper.updateById(record);
        String journalId = approvalForm.getJournalId();
        if (ApprovalFormService.ApproveResult.REJECT == result) {
            // 审批未通过
            lambdaUpdate().eq(ReceivableAdjustment::getId, journalId).set(ReceivableAdjustment::getState, JournalStateEnum.REJECTED.name()).update();
            this.studentRecordService.unlocks(Set.of(record.getStudentRecordId()), ReferenceTypeEnum.ADJUSTMENT, approvalForm.getJournalId());
        } else {
            JournalStateEnum journalStateEnum = JournalStateEnum.APPROVING;
            //  1：审批（默认））2：驳回到发起人）3：驳回上一级）
            if (applyType != null && applyType == 2) {
                journalStateEnum = JournalStateEnum.DRAFT;
                this.studentRecordService.unlocks(Set.of(record.getStudentRecordId()), ReferenceTypeEnum.ADJUSTMENT, approvalForm.getJournalId());
            } else if (applyType != null && applyType == 3) {
                journalStateEnum = JournalStateEnum.PENDING;
            }
            // 审批通过-修改为审核中
            lambdaUpdate().eq(ReceivableAdjustment::getId, journalId).set(ReceivableAdjustment::getState, journalStateEnum.name()).update();
        }
        this.approvalFormService.approve(formID, result, comment, form, applyType);
        log.info("[调价单{}]审批人:{},审批结果:{}", formID, AccountHolder.getRequiredAccountInfo().getName(), result.name());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void cancel(String formID) {
        var approvalForm = this.approvalFormService.getById(formID);
        Assert.notNull(approvalForm, BizExceptionProducer.produce(NemsErrorBodyEnum.DATA_EXIST, "审批单不存在"));
        var record = super.getBaseMapper().selectById(approvalForm.getJournalId());
        Assert.notNull(record, BizExceptionProducer.produce(NemsErrorBodyEnum.DATA_EXIST, "调价单不存在"));
        Assert.isTrue(ReceivableAdjustmentState.canCancel(record.getState()),
                BizExceptionProducer.produce(StudentRecordErrorBodyEnum.WORKFLOW_CANCEL_NO_PENDING, "凭单当前状态不可撤销")
        );
        Assert.isTrue(record.getCreatedBy().equals(AccountHolder.getRequiredAccountInfo().getEmail()),
                BizExceptionProducer.produce(StudentRecordErrorBodyEnum.WORKFLOW_CANCEL_NO_CREATED_BY, "仅允许提交人进行撤单")
        );
        record.setState(ReceivableAdjustmentState.DRAFT);
        super.baseMapper.updateById(record);
        this.studentRecordService.unlocks(Set.of(record.getStudentRecordId()), ReferenceTypeEnum.ADJUSTMENT, approvalForm.getJournalId());
        this.approvalFormService.cancel(formID);
        log.info("[调价单{}]员工:{}操作了单据撤销", formID, AccountHolder.getRequiredAccountInfo().getName());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void rollbackRequester(String formID) {
        var approvalForm = this.approvalFormService.getById(formID);
        Assert.notNull(approvalForm, BizExceptionProducer.produce(NemsErrorBodyEnum.DATA_EXIST, "审批单不存在"));
        var journal = super.getBaseMapper().selectById(approvalForm.getJournalId());
        Assert.notNull(journal, BizExceptionProducer.produce(NemsErrorBodyEnum.DATA_EXIST, "调价单不存在"));
        if (journal.getState().name().equals(JournalStateEnum.DRAFT.name())) {
            return;
        }
        journal.setState(ReceivableAdjustmentState.DRAFT);
        super.baseMapper.updateById(journal);
        this.studentRecordService.unlocks(Set.of(journal.getStudentRecordId()), ReferenceTypeEnum.ADJUSTMENT, approvalForm.getJournalId());
//        this.approvalFormService.cancel(formID);
        log.info("[调价单{}]员工:{}操作了单据撤销", formID, AccountHolder.getRequiredAccountInfo().getName());
    }


    @Transactional(rollbackFor = Exception.class)
    @Override
    public void remind(String formID, String targetAssignee) {
        this.approvalFormService.remind(formID, targetAssignee);
        log.info("[调价单{}]员工:{}操作了催办, 催办对象:{}", formID, AccountHolder.getRequiredAccountInfo().getName(), targetAssignee);
    }
}
